﻿#Requires AutoHotkey v2.0
#SingleInstance Force

CoordMode 'Mouse', 'Screen'

zoom := 2 ; initial magnification, 1..32
Rx := 128 ; half vertical/horizontal side of magnifier window
Ry := 128
Zx := Rx / zoom ; frame x/y size
Zy := Ry / zoom

OnUpdate(GuiObj, MinMax, w, h) {
  global
  Rx := w / 2
  Ry := h / 2
  Zx := Rx / zoom
  Zy := Ry / zoom
}

#x::
OnClose(*) {
  DllCall("gdi32.dll\DeleteDC", 'UInt', hdc_frame)
  DllCall("gdi32.dll\DeleteDC", 'UInt', hdd_frame)
  ExitApp()
}

g := Gui('+AlwaysOnTop +Resize')
g.OnEvent('Size', OnUpdate)
g.OnEvent('Close', OnClose)
g.Show('w' 3 * Rx ' h' 3 * Ry 'x0 y0')

MagnifierID := g.Hwnd
PrintSourceID := 0

hdd_frame := DllCall("GetDC", 'UInt', PrintSourceID)
hdc_frame := DllCall("GetDC", 'UInt', MagnifierID)

SetTimer Repaint, 5

GetClosest := (x, a, b) => x < a ? a : (b < x ? b : x)

Repaint() {
  global
  MouseGetPos(&x, &y)
  xz := GetClosest(x - Zx - 6, 0, A_ScreenWidth - 2 * Zx) ; keep the frame on screen
  yz := GetClosest(y - Zy - 6, 0, A_ScreenHeight - 2 * Zy)
  DllCall("gdi32.dll\StretchBlt", 'UInt', hdc_frame, 'Int'
    , 0, 'Int', 0, 'Int', 2 * Rx, 'Int', 2 * Ry
    , 'UInt', hdd_frame, 'UInt', xz, 'UInt', yz
    , 'Int', 2 * Zx, 'Int', 2 * Zy, 'UInt', 0xCC0020) ; SRCCOPY
}

#a::
{
  static antialize := 0
  DllCall("gdi32.dll\SetStretchBltMode", "uint", hdc_frame, "int", 4 * antialize)  ; Antializing ?
  antialize := !antialize
}

MButton::
{
  static paused := true
  paused
    ? SetTimer(Repaint, 0)
    : SetTimer(Repaint, 5)
  paused := !paused
}

^+WheelUp::
^+WheelDown::
{
  global
  if zoom < 31 and (A_ThisHotKey = "^+WheelUp")
    zoom *= 1.189207115         ; sqrt(sqrt(2))
  if zoom > 1 and (A_ThisHotKey = "^+WheelDown")
    zoom /= 1.189207115
  Zx := Rx / zoom
  Zy := Ry / zoom
}